package main

import (
	"camwall-backend/go/db"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"strconv"
	"strings"
	"time"

	"camwall-backend/go/mahonia"
)

func Register(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	if r.Form["openid"] != nil && r.Form["qq"] != nil {
		fmt.Println("Register: " + r.Form["openid"][0] + " " + r.Form["qq"][0])
		rows, err := db.DB.Query("SELECT * from `accounts` where qq='" + r.Form["qq"][0] + "';")
		if err != nil {
			w.Write([]byte("失败:" + err.Error()))
			return
		} else {
			for rows.Next() {
				w.Write([]byte("失败:此账号已经绑定了微信号,请先发送 #unbinding 以解绑"))
				return
			}

			//未绑定
			_, err = db.DB.Exec("insert into `accounts` (openid,qq,timestamp) values ('" +
				r.Form["openid"][0] + "','" + r.Form["qq"][0] + "'," +
				strconv.FormatInt(time.Now().Unix(), 10) + ")")
			if err != nil {
				w.Write([]byte("失败:" + err.Error()))
				return
			}
			w.Write([]byte("操作成功,请重新进入小程序"))
			return
		}
	} else {
		w.Write([]byte("失败:no openid or qq provided"))
	}
}

func Unbinding(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	if r.Form["qq"] != nil {
		fmt.Println("Unbinding: " + r.Form["qq"][0])
		_, err := db.DB.Exec("delete from `accounts` where qq='" + r.Form["qq"][0] + "'")
		if err != nil {
			w.Write([]byte("失败:" + err.Error()))
			return
		} else {
			w.Write([]byte("操作成功"))
			return
		}
	} else {
		w.Write([]byte("失败:no qq provided"))
	}
}

type account struct {
	QQ   string `json:"qq"`
	Nick string `json:"nick"`
}

type PortraitCallBack map[string]([]interface{})

func Account(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	if r.Form["openid"] != nil { //提供了openid
		fmt.Println("Account: " + r.Form["openid"][0])

		rows, err := db.DB.Query("select qq from `accounts` where openid='" + r.Form["openid"][0] + "'")
		if err != nil {
			w.Write([]byte("失败:" + err.Error()))
			return
		} else {
			accs := make([]account, 0)
			for rows.Next() {
				qq := ""
				_ = rows.Scan(&qq)
				nick := "" //https://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?g_tk=1518561325&uins=后面跟QQ号

				resp, err := http.Get("https://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?g_tk=1518561325&uins=" + qq)
				if err != nil {
					nick = qq
					fmt.Println(err.Error())
				} else {
					if false {
					} else {

						body, err := ioutil.ReadAll(resp.Body)
						if err != nil {
							nick = qq
							fmt.Println(err.Error())
						} else {

							utf8 := mahonia.NewDecoder("gbk").ConvertString(string(body))
							bodyStr := strings.ReplaceAll(utf8, "portraitCallBack(", "")

							bodyStr = bodyStr[:len(bodyStr)-1]
							accountInfo := PortraitCallBack{}
							fmt.Println(bodyStr)
							err = json.Unmarshal([]byte(bodyStr), &accountInfo)
							if err != nil {
								nick = qq
								fmt.Println(err.Error())
							} else {
								nick = accountInfo[qq][6].(string)
							}
						}
					}

				}
				defer resp.Body.Close()

				acc := account{
					QQ:   qq,
					Nick: nick,
				}
				accs = append(accs, acc)
			}

			bytes, err := json.Marshal(accs)
			if err != nil {
				w.Write([]byte("失败:" + err.Error()))
				return
			}
			w.Write(bytes)
		}
	} else {
		w.Write([]byte("失败:no openid provided"))
	}
}

func PostNew(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	if r.Form["text"] != nil && r.Form["media"] != nil && r.Form["anonymous"] != nil && r.Form["qq"] != nil && r.Form["openid"] != nil {
		fmt.Println(r.URL)

		anonymous := 0
		if r.Form["anonymous"][0] == "true" {
			anonymous = 1
		}

		_, err := db.DB.Exec("insert into `posts` (`openid`,`qq`,`timestamp`,`text`,`media`,`anonymous`) values ('" + r.Form["openid"][0] + "','" + r.Form["qq"][0] + "'," + strconv.FormatInt(time.Now().Unix(), 10) + ",'" + r.Form["text"][0] + "','" + r.Form["media"][0] + "'," + strconv.Itoa(anonymous) + ")")
		if err != nil {
			fmt.Println(err)
			w.Write([]byte("failed"))
			return
		}
		w.Write([]byte("操作成功"))
	} else {
		w.Write([]byte("failed:params not satisfied"))
	}
}

func main() {

	fmt.Println("启动http监听..")
	http.HandleFunc("/register", Register)
	http.HandleFunc("/account", Account)
	http.HandleFunc("/unbinding", Unbinding)
	http.HandleFunc("/postnew", PostNew)
	err := http.ListenAndServeTLS(":8989", "cert.pem", "key.pem", nil)
	log.Fatal(err)
}
